/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package utn.tsb.tej.front_end;

import com.trolltech.qt.gui.QCheckBox;
import com.trolltech.qt.gui.QCloseEvent;
import com.trolltech.qt.gui.QComboBox;
import com.trolltech.qt.gui.QDialog;
import com.trolltech.qt.gui.QGridLayout;
import com.trolltech.qt.gui.QHBoxLayout;
import com.trolltech.qt.gui.QHeaderView;
import com.trolltech.qt.gui.QIcon;
import com.trolltech.qt.gui.QLabel;
import com.trolltech.qt.gui.QLineEdit;
import com.trolltech.qt.gui.QMessageBox;
import com.trolltech.qt.gui.QPushButton;
import com.trolltech.qt.gui.QTableWidget;
import com.trolltech.qt.gui.QTableWidgetItem;
import com.trolltech.qt.gui.QVBoxLayout;
import utn.tsb.tej.comunications.Preferences;
import utn.tsb.tej.comunications.RequestResult;
import utn.tsb.tej.comunications.client.ClientRequests;
import utn.tsb.tej.comunications.server.RoomGame;
import utn.tsb.tej.world_logic.Color;
import utn.tsb.tej.world_logic.Player;
import csm.uttils.generics.Roster;

/**
 *
 * @author Carlos S. Moreno <CarlosS.Moreno@gmail.com>
 */
public class RoomGameWindow extends QDialog {

    String serverAddress;
    RoomGame roomGame;
    Player player;
    QLineEdit txtPlayerName;
    QComboBox cmbColor;
    QTableWidget tablePlayers;
    QCheckBox chkReady;
    QPushButton btnExit, btnUpdateTable;

    /**
     * Constructor of RoomGameWindow. It recibes a Player and the address of the
     * server to connect with. Also read the instance of the RoomGame.
     *
     * This window run a thread that is constantly asking the sever for the
     * RoomGame Data to update the data showed on the window.
     *
     * When something is changed, like the player data, it is send the information
     * about the change to the server.
     * @param player Object player that represent the client
     * @param serverHost The server host address
     */
    public RoomGameWindow(Player player, String serverHost)
    {
        this.roomGame = RoomGame.getInstance();
        this.player = player;
        serverAddress = serverHost;

        initComponents();
        
        loadColors();
        updateTable();

        btnUpdateTable.clicked.connect(this, "btnUpdateTable_clicked()");
        txtPlayerName.editingFinished.connect(this, "txtPlayerName_editingFinished()");
        cmbColor.currentIndexChanged.connect(this, "cmbColor_currentIndexChanged()");
    }

    private void initComponents() {
        this.setWindowTitle("T.E.J. - " + roomGame.getRoomName());
        this.setMinimumSize(600, 320);
        this.setMaximumSize(0, 0);
        QVBoxLayout mainLayout = new QVBoxLayout(this);
        //Player Data
        QGridLayout playerLayout = new QGridLayout();
        playerLayout.addWidget(new QLabel("Nickname:"), 0, 0);
        txtPlayerName = new QLineEdit(Preferences.getNickname());
        playerLayout.addWidget(txtPlayerName, 1, 0);
        playerLayout.addWidget(new QLabel("Color:"), 0, 1);
        cmbColor = new QComboBox();
        cmbColor.setMaximumWidth(200);
        playerLayout.addWidget(cmbColor, 1, 1);
        mainLayout.addLayout(playerLayout);

        //Players Table
        QHBoxLayout tableTitle = new QHBoxLayout();
        tableTitle.addWidget(new QLabel("Players:"));
        QIcon icoUpdate = new QIcon(getClass().getResource("/images/update.png").getPath());
        btnUpdateTable = new QPushButton(icoUpdate, "Update Table");
        tableTitle.addWidget(btnUpdateTable);
        mainLayout.addLayout(tableTitle);
        //Players Table
        tablePlayers = new QTableWidget(6, 5);
        tablePlayers.horizontalHeader().setResizeMode(QHeaderView.ResizeMode.Fixed);
        tablePlayers.setHorizontalHeaderItem(0, new QTableWidgetItem("Nº"));
        tablePlayers.setHorizontalHeaderItem(1, new QTableWidgetItem("Tipo"));
        tablePlayers.setHorizontalHeaderItem(2, new QTableWidgetItem("Jugador"));
        tablePlayers.setHorizontalHeaderItem(3, new QTableWidgetItem("Color"));
        tablePlayers.setHorizontalHeaderItem(4, new QTableWidgetItem("Listo"));
        tablePlayers.setColumnWidth(0, 30);
        tablePlayers.setColumnWidth(1, 80);
        tablePlayers.setColumnWidth(2, 360);
        tablePlayers.setColumnWidth(3, 50);
        tablePlayers.setColumnWidth(4, 50);
        tablePlayers.verticalHeader().setResizeMode(QHeaderView.ResizeMode.ResizeToContents);
        tablePlayers.horizontalHeader().setStretchLastSection(true);
//        tablePlayers.horizontalHeader().hide();
        tablePlayers.verticalHeader().hide();
        //adding the table
        mainLayout.addWidget(tablePlayers);

        //Bottom Layout
        QHBoxLayout bottomLayout = new QHBoxLayout();
        //Checkbox "Ready"
        chkReady = new QCheckBox("I'm Ready");
        chkReady.stateChanged.connect(this, "chkReady_stateChanged()");
        bottomLayout.addWidget(chkReady);
        btnExit = new QPushButton("Exit Room Game");
        bottomLayout.addWidget(btnExit);

        mainLayout.addLayout(bottomLayout);
        this.setModal(true);
    }

    private void loadColors()
    {
        cmbColor.clear();
        cmbColor.addItem(getColorIcon(player.getColor().getCodeRGB()),
                    player.getColor().toString(),
                    player.getColor());

        Roster<Color> colors = roomGame.getAllAvailableColors();
        colors.startIterator();
        while (colors.hasNext() && cmbColor.count() <= colors.count())
        {
            Color color = colors.next();
            cmbColor.addItem(getColorIcon(color.getCodeRGB()),
                    color.toString(),
                    color);
        }
    }


    private QIcon getColorIcon(String rgb)
    {
        QIcon icon = new QIcon();
        if(rgb.compareToIgnoreCase(Color.RED)==0){
            icon = new QIcon(getClass().getResource("/images/Red_Ball1.png").getPath());
        }
          if(rgb.compareToIgnoreCase(Color.BLACK)==0){
            icon = new QIcon(getClass().getResource("/images/Black_Ball1.png").getPath());
        }
          if(rgb.compareToIgnoreCase(Color.GREEN)==0){
            icon = new QIcon(getClass().getResource("/images/Green_Ball1.png").getPath());
        }
          if(rgb.compareToIgnoreCase(Color.BLUE)==0){
            icon = new QIcon(getClass().getResource("/images/Blue_Ball1.png").getPath());
        }
          if(rgb.compareToIgnoreCase(Color.WHITE)==0){
            icon = new QIcon(getClass().getResource("/images/Fuccia_Ball1.png").getPath());
        }
          if(rgb.compareToIgnoreCase(Color.YELLOW)==0){
            icon = new QIcon(getClass().getResource("/images/Yellow_Ball1.png").getPath());
        }
        return icon;
    }

    /**
     * Thes method update the table with the data seted on the RoomGame object.
     * It shouldn't be call directly, endeed the updateRoomGame it will call
     * it.
     */
    public void updateTable()
    {
        tablePlayers.clearContents();
        Roster<Player> players = roomGame.getPlayers();
        players.startIterator();

        Player otherPlayer;
        int r = 0;
        while (players.hasNext())
        {
            otherPlayer = players.next();
            tablePlayers.setCellWidget(r, 0, new QLabel(String.valueOf(r+1)));//Number
            if (otherPlayer.getType() == Player.TYPE_CPU)//Type
                tablePlayers.setCellWidget(r, 1, new QLabel("CPU"));
            else
                tablePlayers.setCellWidget(r, 1, new QLabel("User"));
            tablePlayers.setCellWidget(r, 2, new QLabel(otherPlayer.getNickName()));//Player
            QIcon colorIcon = getColorIcon(otherPlayer.getColor().getCodeRGB());
            tablePlayers.setItem(r, 3, new QTableWidgetItem(colorIcon, ""));//Color
            
            QIcon ready;
            if (otherPlayer.isReady())
                ready = new QIcon(getClass().getResource("/images/ready.png").getPath());
            else
                ready = new QIcon(getClass().getResource("/images/not_ready.png").getPath());
            tablePlayers.setItem(r, 4, new QTableWidgetItem(ready, ""));//Color
            r++;
        }
    }

    /**
     * This method call the server asking for the las data of the RoomGame.
     * Then, it update the table view on the window.
     */
    private void updateRoomGame()
    {
        ClientRequests client = new ClientRequests(serverAddress);
        RequestResult rResult = client.requestRoomGameUpdate();
        if (rResult.isSuccess()) {
            roomGame = RoomGame.getInstance();
            updateTable();
            loadColors();
            System.out.println("Table Updated");
        } else {
            new QMessageBox(rResult.getIcon(),
                    rResult.getTitle(),
                    rResult.getText()).show();
        }
    }

    /**
     * Thsi method sends a updated player's data.
     * And update the roomgame and the table view by calling the updateRoomGame
     * method.
     */
    private void sendUpdatePlayer()
    {
        player.setNickName(txtPlayerName.text());
        player.setReady(chkReady.isChecked());
        if (cmbColor.currentIndex() > -1)
            player.setColor((Color)cmbColor.itemData(cmbColor.currentIndex()));

        ClientRequests client = new ClientRequests(serverAddress);
        RequestResult updateResult = client.requestUpdatePlayer(player);
        if (!updateResult.isSuccess())
        {
            if (updateResult.getRequestObject() != null)
                player.setColor((Color)updateResult.getRequestObject());
            new QMessageBox(updateResult.getIcon(),
                    updateResult.getTitle(),
                    updateResult.getText()).show();
        }
        updateRoomGame();
    }

    private void chkReady_stateChanged()
    {
        txtPlayerName.setEnabled(!chkReady.isChecked());
        cmbColor.setEnabled(!chkReady.isChecked());
        sendUpdatePlayer();
    }

    private void btnUpdateTable_clicked()
    {
        updateRoomGame();
    }

    public void txtPlayerName_editingFinished()
    {
        if (player.getNickName().compareTo(txtPlayerName.text()) != 0)
            sendUpdatePlayer();
    }

    public void cmbColor_currentIndexChanged()
    {
        Color aux = (Color)cmbColor.itemData(cmbColor.currentIndex());
        if (cmbColor.currentIndex() > -1 && player.getColor().compareTo(aux) != 0)
            sendUpdatePlayer();
    }
}//Class RoomGameWindow
